#include <avr/io.h> 
#include <avr/interrupt.h>

//#include <util/delay.h>
#include "Serial.h"
#include "timer0.h"


//#include <avr/interrupt.h>

#define BaudRate 76800
#define MYUBRR 25 //((F_CPU / 16 / BaudRate ) - 1 )

//Time in ms for 4 character times
#define EOM_LEN 1000//(unsigned char)((1000*4)/(BaudRate/8))

unsigned char rx[BUFF_SIZE];
unsigned char rxHead;
unsigned char rxTail;

unsigned long lastRx;

ISR(USART0_RX_vect)
{
	volatile unsigned char i;
	volatile unsigned char head = rxHead;
	volatile unsigned char tail = rxTail;
	volatile unsigned char *ptr = rx;

	i = (head + 1) % BUFF_SIZE;
	if(i != tail)
	{
		ptr[head] = UDR0;
		head = i;
	}

	rxHead = head;
	rxTail = tail;
}


void serialInit(void)
{
 	/*Set baud rate */ 
	UBRR0H = (unsigned char)(MYUBRR>>8); 
	UBRR0L = (unsigned char) MYUBRR; 
	/* Enable receiver and transmitter and recieve interrupt  */
	UCSR0B = _BV(RXEN0) | _BV(TXEN0) | _BV(RXCIE0); 
	/* Frame format: 7data, odd parity, 2stop bit */ 
//	UCSR0C = _BV(UPM00) | _BV(UPM01) | _BV(USBS0) | _BV(UCSZ01);
	/* Frame format: 7data, odd parity, 2stop bit */ 
	UCSR0C =  _BV(UCSZ01)| _BV(UCSZ00);
}


unsigned char serialCheckRxComplete(void)
{
	return( UCSR0A & _BV(RXC0)) ;		// nonzero if serial data is available to read.
}

unsigned char serialCheckTxReady(void)
{
	return( UCSR0A & _BV(UDRE0) ) ;		// nonzero if transmit register is ready to receive new data.
}

unsigned char serialCheckTxComplete(void)
{
	return( UCSR0A & _BV(TXC0)) ;		// nonzero if serial data has been sent.
}

void serialClearTxComplete(void)
{
	UCSR0A |= _BV(TXC0);		// nonzero if serial data has been sent.
}

unsigned char serialRead(void)
{
	while (serialCheckRxComplete() == 0)		// While data is NOT available to read
	{;;} 
	return UDR0;
}

void serialWrite(unsigned char DataOut)
{
	while (serialCheckTxReady() == 0)		// while NOT ready to transmit 
	{;;} 
	UDR0 = DataOut;
	while(serialCheckTxComplete() == 0)
	{;;}
	serialClearTxComplete();
}

void rsWrite(unsigned char *str, unsigned char len)
{
	int i;
	//Disable the receive interrupt
	UCSR0B &= ~_BV(RXCIE0); 

	for(i=0;i<len;i++)
	{
		serialWrite(str[i]);
	}
	//Turn the receive interrupt
	UCSR0B |= _BV(RXCIE0); 
}

unsigned char rsCheck(void)
{
	int i;
	
	for(i=0;i<BUFF_SIZE;i++)
	{
		if(rx[i]=='\n')
			return(i+1);
	}
	return(0);
}

unsigned char rsRead(unsigned char *str)
{
	unsigned char len = 0;
	unsigned char i;
	unsigned char eom;
	
	eom = rsCheck();
	if(!eom)
	 return 0;
	 eom--;
	
	i=rxTail;
	
	while(i!=eom)
	{
		str[len]=rx[i];
		rx[i]=0;
		i=(i+1) % BUFF_SIZE;
		len++;
	}
	rx[eom] = 0;
	rxTail = (eom+1) % BUFF_SIZE;
	
	str[len+1] = 0;
	return len;
}

